/**
* mpsvr net进程的客户端socket处理
* @author thinkry
*/

#ifndef __MPSVR_NETCLIENT_H__
#define __MPSVR_NETCLIENT_H__

#include "mpdef.h"
#include "net/CTEpoll.h"
#include "net/CTSocket.h"
#include "CTBuffer.h"

class CMpNet;

/**
* 只在CMpNet中使用，所以方法都是protected，并设为CMpNet的友元
*/
class CMpNetClient: public CTEpollObject<CMpNet>
{
protected:
    CTSocket        m_stSock;
    CMpNet*         m_pstNet;
    CTBuffer        m_stRecvBuffer;
    CTBuffer        m_stSendBuffer;

    // 这几个变量与Handle进程自动释放有关
    int             m_iRunCount;    ///< Handle进程运行的次数
    int             m_iMaxRumCount; ///< 最大运行次数
    time_t          m_iCreateTime;  ///< Handle进程的创建时间
    static time_t   ms_iLastFreeTime; ///< 最后一次释放Handle进程的时间

    friend class CMpNet;

public:
    CMpNetClient(): 
        m_stSock(PF_LOCAL, SOCK_STREAM, false),
        m_pstNet(NULL),
        m_iRunCount(0),
        m_iMaxRumCount(0)
    {
        m_iCreateTime = time(0);
    }

    virtual ~CMpNetClient()
    {
        //必须先将socket从epoll中剔除然后再close socket
        Unregister();
    }

protected:
    void Init(CMpNet& stNet, SOCKET iSocket, int iMaxRunCount);

    /**
    * 是否到了最大执行次数
    */
    bool IsReachMaxRunCount();

    /**
    * 发送缓冲区的操作
    */
    void GetSendBuffer(char*& pszBuffer, int& iBufferLen);

    /**
    * 接收一个Code
    * @param[out] iCodeLen Code的长度 没有Code或Code没接收完整时为0
    * @return 0表示成功 没有Code或Code没接收完整时也算成功
    */
    void RecvOneCode(char*& pszCode, int& iCodeLen);

    /**
    * 一个Code已经被上层处理了，要删除这个Code
    */
    void RemoveOneCode(int iCodeLen);

    /**
    * 发送一个Code
    */
    void SendOneCode(int iCodeLen);
};

#endif //__MPSVR_NETCLIENT_H__
